<?php
namespace adminv1;

use common\utils\OutputExecl;
use Yii;
use yii\web\Response;
use admin\models\auth\User;
use common\utils\Model;


/**
 * 接口基础处理
 * @author Administrator
 * @param  所有版本接口的控制器父类
 */
abstract class CoreController extends \yii\rest\ActiveController
{
    public  $modelClass = '';
    public  $_user;  //用户信息
    public  $_uid;
    public $curDateTime;
    protected $request = [];

    protected abstract function getModelClass(): string;

    public function beforeAction($action)
    {
        $this->request = array_merge(
            Yii::$app->request->post(),
            Yii::$app->request->get(),
            $_FILES
        );
        $this->curDateTime = date("Y-m-d H:i:s");

        $mod = ['no-auth', 'common'];
        $actionMod = ['reg','login','test', 'export'];
        $controller = Yii::$app->controller->id;
        $actionName = Yii::$app->controller->action->id;

        if(in_array($controller, $mod) || in_array($actionName, $actionMod)) return true;

        if(!isset($this->request['auth_key'])) return $this->error('auth_key is null.','200','404');

        $this->_user = User::loginByAuthkey(['auth_key' => $this->request['auth_key']]);

        if(empty($this->_user)) return $this->error('用户不存在', '200', '404');
        $this->_uid = $this->_user['id'];

        ## 接口权限验证
        if(\Yii::$app->params['apiAuth']) {
            $apiAuth = \Yii::$app->cache->get('userApiCache_'.$this->_uid);
            if(!$apiAuth) $apiAuth =  [];
            $apiAuth = array_merge($apiAuth, \Yii::$app->params['ignore_api']);

            if(!in_array('v1/'.$controller.'/'.$actionName, $apiAuth)){
                $this->error('你没有此权限,请联系管理员','200','403');
                return false;
            }
        }
        return true;
    }

    public function request($key,$default = '')
    {
        $request = array_merge(Yii::$app->request->post(), Yii::$app->request->get(), $_FILES);
        return $request[$key] ?? $default;
    }


    public function success($msg='', $res = [], $extend = []) {
        $data = [
            'status' => "200"  ,
            'code'   => 0,
            'msg'    => (string)$msg,
            'data'   => $res,
        ];
        if($extend) $data['extend'] = $extend;
        return $this->send($data);
    }

    public function error($msg='', $status = '200', $code = 1)
    {
        $data = [
            'status'=> $status."",
            'code'  => $code,
            'msg'   => (string)$msg,
        ];
        return  $this->send($data);
    }

    public function send($data = [])
    {
        $out = json_encode($data, JSON_UNESCAPED_UNICODE);
        die($out);
    }

    ## 列表
    public function actionList()
    {
        $whereArr = $this->getWhere();
        $params = array(
            'field'	=> ['*'],
            'page'	=> $this->request('page',1),
            'limit'	=> $this->request('page_size',10),
            'order' => 'id desc',
        );

        $data = $this->getModelClass()::dataList($whereArr, $params);
        $totalNums = 0;
        $totalNums = $this->getModelClass()::$totalNums;
        return $this->success('数据列表', $data, ['totalNums' => $totalNums]);
    }

    ## 组装条件
    protected function getWhere(): array
    {
        $where = $and = [];
        $search = $this->request('search');
        $search = $search ? json_decode($search,1) : '';
        if(!$search) return [];

        foreach($search as $key => $val)
        {
            if(!$val) continue;
            if($key == 'date')
            {
                if(!$val['0'] || !$val['1']) continue;
                $and[] = ['between', 'create_time', strtotime($val[0]), strtotime($val[1])];
            }else
            {
                $where[$key] = $val;
            }
        }
        return ['where' => $where, 'and' => $and];
    }

    ## 信息
    public function actionInfo()
    {
        $id = $this->request('id');
        if(!$id) return $this->error('参数有误');
        $data = $this->getModelClass()::find()->where(['id' => $id])->asarray()->one();
        return $this->success('数据', $data);
    }

    ## 添加、编辑
    public function actionEdit()
    {
        $id = $this->request('id');

        $class =  "\\".$this->getModelClass();
        $model = new $class;

        if($id)
        {
            $model = $this->getModelClass()::findOne(['id' => $id]);
            if(!$model) return $this->error('参数有误');
        }else{
            $this->request['create_time'] = $this->curDateTime;
        }
        $this->request['update_time'] = $this->curDateTime;

        if(!$model->load($this->request, '') || !$model->validate() || !$model->save(false)){
            return $this->error('操作失败');
        }

        return $this->success('操作成功');
    }

    ## 删除
    public function actionDel()
    {
        if(!$id = $this->request('id')) $this->error('参数有误');

        $res = $this->getModelClass()::deleteAll(['id'=>$id]);

        if(!$res) return $this->error('删除失败');
        return $this->success('删除成功');
    }


    //导出
    public function actionExport()
    {
        $whereArr  = $this->getWhere();
        $params = array(
            'order' => 'id desc',
        );

        $class =  "\\".$this->getModelClass();
        $model = new $class;

        $list = $model::dataList($whereArr, $params);

        ## 导出头部处理
        $attributeLabels = $model->attributeLabels();
        $k = 0;
        $outputKey = \Yii::$app->params['outputKey'];
        ## 需要导出的字段
        $valueKey = [];
        $headData = [];
        foreach($attributeLabels as $key => $name)
        {
            if(in_array($key, [])) continue;
            $headData[$outputKey[$k]] = $name;
            $valueKey[] = $key;
            $k++;
        }

        ## 组织导出数据
        $exportData = [];
        foreach($list as $val)
        {
            $temp = [];
            foreach($valueKey as $vkey)
            {
                $temp[] = $val[$vkey];
            }
            $exportData[] = $temp;
        }

        $fileName = date('YmdHis') . '.xls';
        $execlObj = new OutputExecl();
        $res = $execlObj->output($headData, $exportData, $fileName);
        if($res)
            return $this->success('下载地址', array('url' => $res));
        else
            return $this->error('导出失败');
    }


}


